﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using log4net;
using SR;



namespace DSServer.Server
{
    class Signer
    {
        /// <summary>
        /// set true if you with run server in siging mode
        /// </summary>
        private static readonly bool doSign = false;

        private static readonly ILog log = log4net.LogManager.GetLogger(typeof(Signer));
        private static readonly string signerString = "certsigner2013:tcp -h 149.156.97.155 -p 2002";
        private static readonly string openSSLDir = "OpenSSL";
        private static readonly string name = "Michal";
        private static readonly string surname = "Janiec";
        private static readonly string requestExt = ".csr";
        private static readonly string responseExt = ".crt";


        public static void Sign(Ice.Communicator ic)
        {
            if (!doSign)
                return;

            Signer signer = new Signer(ic);
            signer.signIt();
            throw new Exception("Only signing");
        }

        private Ice.ObjectPrx ca;
        private Ice.Communicator ic;

        private Signer(Ice.Communicator ic)
        {
            this.ic = ic;
        }

        private byte[] Invoke(byte[] request)
        {
            byte[] inParams;
            byte[] outParams;

            try
            {
                inParams = PrepareParams(request);

                if (ca.ice_invoke("signCSR", Ice.OperationMode.Normal, inParams, out outParams))
                    return HandleSucces(outParams);
                else
                    HandleUserExceptions(outParams);
            }
            catch (Ice.LocalException ex)
            {
                log.Error(ex);
            }
            return null;
        }

        private byte[] PrepareParams(byte[] request)
        {
            Ice.OutputStream outStream;

            outStream = Ice.Util.createOutputStream(ic);
            outStream.startEncapsulation();
            outStream.writeString(name);
            outStream.writeString(surname);
            outStream.writeByteSeq(request);
            outStream.endEncapsulation();
            return outStream.finished();
        }

        private byte[] HandleSucces(byte[] outParams)
        {
            byte[] result;
            Ice.InputStream inStream;
            inStream = Ice.Util.createInputStream(ic, outParams);
            inStream.startEncapsulation();
            result = inStream.readByteSeq();
            inStream.endEncapsulation();
            return result;
        }

        private void HandleUserExceptions(byte[] outParams)
        {
            Ice.InputStream inStream;
            try
            {
                inStream = Ice.Util.createInputStream(ic, outParams);
                inStream.startEncapsulation();
                inStream.throwException();
            }
            catch (Ice.UserException e)
            {
                log.Error(e);
            }
        }

        private void signIt()
        {
            ca = ic.stringToProxy(signerString);
            
            string[] files = Directory.GetFiles(openSSLDir);
            string certFile;
            byte[] request;
            byte[] response;

            foreach (string file in files)
            {
                if (file.EndsWith(requestExt))
                {
                    CertSignerPrx caprx = CertSignerPrxHelper.checkedCast(ca);
                    request = File.ReadAllBytes(file);
                    response = caprx.signCSR(name, surname, request);
                    //response = Invoke(request);
                    certFile = file.Substring(0,file.Length-requestExt.Length);
                    File.WriteAllBytes(certFile+responseExt, response);
                }
            }

        }
    }
}
